This document provides a comprehensive guide to creating interactive maps using the leaflet package in R. We will explore various features of leaflet, from basic map creation to advanced customizations like adding markers, popups, and choropleth layers. This guide is intended for users who have a basic understanding of R and are interested in data visualization and geospatial analysis.
1 Getting Started: Loading Libraries and Data
First, we need to load the necessary R libraries. We’ll be using tidyverse for data manipulation, sf for working with spatial data, leaflet for creating the maps, and geojsonio for reading GeoJSON files.
Code
# Load the tidyverse package for data manipulation and visualization.library(tidyverse)# Load the sf package for working with simple features, a standardized way to encode spatial vector data.library(sf)# Load the leaflet package for creating interactive maps.library(leaflet)# Load the geojsonio package for reading and writing GeoJSON.library(geojsonio)# Load the leaflet.extras package for additional leaflet features.library(leaflet.extras)
2 Displaying a Basic Map with OpenStreetMap
Here, we’ll create a simple map using the default OpenStreetMap tiles and add a marker for a specific location.
Code
# Create a leaflet map widget.m <-leaflet() %>%# Add the default OpenStreetMap map tiles.addTiles() %>%# Add a marker to the map at the specified longitude and latitude.addMarkers(lng=174.768, lat=-36.852, popup="The birthplace of R")# Display the map.m
3 Using Google Maps as a Basemap
Instead of the default OpenStreetMap, you can use other tile providers like Google Maps.
Code
leaflet() |># Add Google Maps tiles using the specified URL template.addTiles(urlTemplate ="https://mt1.google.com/vt/lyrs=m&x={x}&y={y}&z={z}") |># Set the initial view of the map with a specific center and zoom level.setView(116.347817690225, 39.997202126977, zoom =16) |># Add a marker to the map.addMarkers(116.347817690225, 39.997202126977)
4 Using Third-Party Map Providers
Leaflet supports a wide variety of third-party map providers. You can find a list of available providers in the providers object.
Code
# You can uncomment these lines to try a different map provider.# m <- leaflet() %>% setView(lng = -71.0589, lat = 42.3601, zoom = 10)# m %>% addProviderTiles(providers$Stadia.StamenToner)
5 Adding Popups
Popups are small boxes containing arbitrary HTML that point to a specific point on the map.
Code
# Create HTML content for the popup.content <-paste(sep ="<br/>","<b><a href='https://www.samurainoodle.com/'>Samurai Noodle</a></b>","606 5th Ave. S","Seattle, WA 98138")# Create a map and add a popup.leaflet() %>%addTiles() %>%setView(-122.327298, 47.597131,zoom =12) %>%addPopups(-122.327298, 47.597131, content,# You can customize the popup options, for example, to remove the close button.options =popupOptions(closeButton =FALSE) )
6 Adding Markers from a Data Frame
You can add multiple markers to a map from a data frame.
Code
# Load the htmltools package for working with HTML.library(htmltools)# Create a data frame with marker information.df <-read.csv(textConnection("Name,Lat,LongSamurai Noodle,47.597131,-122.327298Kukai Ramen,47.6154,-122.327157Tsukushinbo,47.59987,-122.326726"))# Create a map and add markers from the data frame.leaflet(df) %>%addTiles() %>%addMarkers(~Long, ~Lat, popup =~htmlEscape(Name))
7 Adding Labels
Labels are similar to popups but are always displayed or displayed on mouseover.
Code
# Load the htmltools package.library(htmltools)# Create a data frame with marker information.df <-read.csv(textConnection("Name,Lat,LongSamurai Noodle,47.597131,-122.327298Kukai Ramen,47.6154,-122.327157Tsukushinbo,47.59987,-122.326726"))# Create a map and add markers with labels.leaflet(df) %>%addTiles() %>%addMarkers(~Long, ~Lat, label =~htmlEscape(Name))
8 Creating a World Choropleth Map
Now, let’s create a choropleth map of the world, where countries are colored based on their per capita GDP.
8.1 Loading Geospatial and GDP Data
We’ll start by loading the world administrative boundaries from a GeoJSON file and then merge it with per capita GDP data from an Excel file.
Code
# The maptools package is now archived, so we are not using it.# install.packages("https://cran.r-project.org/src/contrib/Archive/maptools/maptools_1.1-8.tar.gz")
Code
# Read the world administrative boundaries from a GeoJSON file.json_data=read_sf("world-administrative-boundaries.geojson")
Code
# Convert the sf object to a data frame.map_df <-as.data.frame(json_data)
Code
# This is an example of how you could create a data frame manually.# name<-c("Ghana", "Grenada", "Guyana", "India", "Jamaica", "Kenya", "United States","Canada")# val<-c(1,2,4,5,5,1000,20000, 100)# per_gdp_usd<-data.frame(name,val)
Code
# Load the openxlsx and readxl packages for reading Excel files.library(openxlsx)library(readxl)# Read the world GDP data from an Excel file and clean up the country names to match the GeoJSON data.per_gdp_usd=read_excel('world data.xlsx') %>%mutate(name=case_when( name =="United States"~"United States of America", name =="Russia"~"Russian Federation", name =="U.K. of Great Britain and Northern Ireland"~"United Kingdom", name =="South Korea"~"Republic of Korea", name =="Lao People's Democratic Republic"~"Laos",TRUE~ name ))
8.2 Merging and Preparing the Data
We’ll merge the geospatial data with the GDP data and convert it back to an sf object.
Code
# These lines are for debugging and checking the data.# test=full_join(map_df, per_gdp_usd, by="name")# left =test %>% filter(is.na(iso3)==TRUE)# right=test %>% filter(is.na(per_gdp_total)==TRUE)
Code
# Merge the map data frame with the GDP data frame by country name.map_df002 <-merge(map_df, per_gdp_usd, by.x ="name", by.y ="name")
Code
# Get a glimpse of the merged data frame.glimpse(map_df002)
# Convert the merged data frame back to an sf object.map_sf002 <- sf::st_as_sf(map_df002, sf_column_name ="geometry")
8.3 Creating the Choropleth Map
Now we can create the choropleth map.
Code
# Create a color palette for the choropleth map.pal <-colorNumeric("viridis", NULL)# Create the leaflet map.leaflet(map_sf002) %>%addTiles() %>%# Add polygons to the map, representing the countries.addPolygons(smoothFactor =0.3, fillOpacity =0.5,weight =1,# Set the fill color based on the per capita GDP.fillColor =~pal(per_gdp_usd),# Create a popup with information about the country.popup =~paste0("地区:", name, "<br/>","<hr/>","人均gpd:", per_gdp_usd, "(千 美元)", "<br/>" ),# Create a label with more detailed information.label =lapply(paste0("地区:", "<b>", map_sf002$name, "</b>", "<br/>","人均gpd 美元:", round(map_sf002$per_gdp_usd/1000), "K <br/>","总gpd 美元:", round(map_sf002$per_gdp_total/1000000), "M <br/>" ), htmltools::HTML) ) %>%# Add a legend to the map.addLegend(position ="bottomright", title ="人均gpd(美元)",pal = pal, values =~per_gdp_usd, opacity =1.0 )
9 China Maps
Now we will create several maps of China, including a map of a single city, a choropleth map of all provinces, and a map of a single province with its cities.
9.1 China One City Map (Shenzhen)
Here, we’ll create a map of Shenzhen.
Code
# Read the GeoJSON data for Shenzhen.json_data <- sf::read_sf("./GeoMapData_CN/citys/440300.json")# You can also load the data directly from a URL.# json_data=read_sf("https://geo.datav.aliyun.com/areas_v2/bound/440300_full.json")
Shenzhen City: ::: {.cell}
Code
# Create a color palette.pal <-colorNumeric("viridis", NULL)# Create the map of Shenzhen.leaflet(json_data) %>%addTiles() %>%addPolygons(smoothFactor =0.3, fillOpacity =0.1)
:::
9.2 All China Each Province GDP Map
Next, we’ll create a choropleth map of China’s provinces, colored by their per capita GDP in 2022.
Code
# Read the GeoJSON data for China's provinces.json_data=read_sf("https://geo.datav.aliyun.com/areas_v2/bound/100000_full.json")
China 2022 Per Capita GDP by Province (USD):
Code
# Load the openxlsx and readxl packages.library(openxlsx)library(readxl)# Read the GDP data for China's provinces.per_gdp_usd=read_excel('china gdp2022.xlsx')
Code
# Convert the sf object to a data frame.map_df <-as.data.frame(json_data)
Code
# Merge the map data with the GDP data.map_df002 <-merge(map_df, per_gdp_usd, by.x ="name", by.y ="city")
Code
# Convert the merged data frame back to an sf object.map_sf002 <- sf::st_as_sf(map_df002, sf_column_name ="geometry")
GDP data source: National Bureau of Statistics of China
9.3 China One Province Map with Each City’s GDP (Guangdong)
Here, we’ll create a choropleth map of Guangdong province, with each city colored by its per capita GDP in 2021.
Code
# Read the GeoJSON data for Guangdong province.json_data <- sf::read_sf("./GeoMapData_CN/province/440000.json")
Guangdong 2021 Per Capita GDP by City (USD):
Code
# Load the openxlsx and readxl packages.library(openxlsx)library(readxl)# Read the GDP data for Guangdong's cities.per_gdp_usd=read_excel('guangdong city gdp2021.xlsx')
Code
# Convert the sf object to a data frame.map_df <-as.data.frame(json_data)
Code
# Merge the map data with the GDP data.map_df002 <-merge(map_df, per_gdp_usd, by.x ="name", by.y ="city")
Code
# Convert the merged data frame back to an sf object.map_sf002 <- sf::st_as_sf(map_df002, sf_column_name ="geometry")
Data source: Guangdong Statistical Yearbook 2022 ::: {.cell}
This section shows how to create a simple map of China’s provinces and add markers for the provincial capitals.
Code
# Load the leaflet and sf packages.library(leaflet)library(sf)# Read the GeoJSON data for China's provinces.json_data <- sf::read_sf("./GeoMapData_CN/china.json")# You can also load the data from a URL.# json_data=read_sf("https://geo.datav.aliyun.com/areas_v2/bound/100000_full.json")# Create a color palette.pal <-colorNumeric("viridis", NULL)# Create the map of China's provinces.m=leaflet(json_data) %>%addTiles() %>%addPolygons(smoothFactor =0.3, fillOpacity =0.1)# Display the map.m
10.1 Add Provincial Capitals
Now, let’s add the provincial capitals to the map.
Code
# Read the GeoJSON data for China's provinces.China=read_sf("https://geo.datav.aliyun.com/areas_v2/bound/100000_full.json")
Code
# Extract the coordinates of the provincial capitals.China002=China %>%as_data_frame() %>%mutate(center2=as.character(center) %>%str_replace('c','_')%>%str_replace('[(]','') %>%str_replace('[)]','') )
Code
# Separate the coordinates into x and y columns.China003=China002%>%separate(center2, c("x", "y"), ", ")
Code
# Add the provincial capitals to the map.China_point = China003 %>%slice(-35)m %>%addCircles(data = China_point,lng =~as.numeric(x), lat =~as.numeric(y),color ="red",weight =10,fillOpacity =2)
11 China Province and City Map
This section demonstrates how to load and combine GeoJSON files for all provinces and their cities.
Code
# Get a list of all province GeoJSON files.map_list <-lapply(X =list.files("./GeoMapData_CN/province", recursive = T, full.names = T),FUN = sf::read_sf)# Print the number of files.length(map_list)
[1] 34
Code
# Check for any files that don't have 10 columns.for (i inc(1:length(map_list))){#print(i)#print(dim(map_list[[i]]))#print(ncol(map_list[[i]]))if(ncol(map_list[[i]])!=10){print(map_list[[i]])} }
Simple feature collection with 1 feature and 4 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: 119.3183 ymin: 21.75147 xmax: 124.5656 ymax: 25.92592
Geodetic CRS: WGS 84
# A tibble: 1 × 5
adcode name center level geometry
<chr> <chr> <chr> <chr> <MULTIPOLYGON [°]>
1 710000 台湾省 121.509062,25.044332 province (((119.5543 23.68248, 119.555 23.…
Code
# Exclude some problematic files.X =list.files("./GeoMapData_CN/province", recursive = T, full.names = T)X2=X[-which(X %in%c("./GeoMapData_CN/province/710000.json" ))]# Reload the list of files.map_list <-lapply(X = X2,FUN = sf::read_sf)
Code
# Print the number of files.length(map_list)
[1] 33
Code
# Combine all the sf objects into one.province_map <-Reduce("rbind", map_list)
Code
# This code would display the combined map.# library(leaflet)# library(sf)## json_data <- province_map### pal <- colorNumeric(c("red", "green", "blue"), 1:10)## leaflet(json_data) %>%# addTiles() %>%# addPolygons(smoothFactor = 0.3, fillOpacity = 0.1)
12 China City and District Map
This section is similar to the previous one, but it loads GeoJSON files for cities and their districts.
Code
# Get a list of all city GeoJSON files.map_list <-lapply(X =list.files("./GeoMapData_CN/citys", recursive = T, full.names = T),FUN = sf::read_sf)# Print the number of files.length(map_list)
[1] 334
Code
# Check for any files that don't have 10 columns.for (i inc(1:length(map_list))){#print(i)#print(dim(map_list[[i]]))#print(ncol(map_list[[i]]))if(ncol(map_list[[i]])!=10){print(map_list[[i]])} }
Simple feature collection with 1 feature and 4 fields
Geometry type: POLYGON
Dimension: XY
Bounding box: xmin: 113.5215 ymin: 22.65421 xmax: 114.2603 ymax: 23.14205
Geodetic CRS: WGS 84
# A tibble: 1 × 5
adcode name center level geometry
<chr> <chr> <chr> <chr> <POLYGON [°]>
1 441900 东莞市 113.746262,23.046237 city ((114.2292 22.81251, 114.2278 22.813…
Simple feature collection with 1 feature and 4 fields
Geometry type: POLYGON
Dimension: XY
Bounding box: xmin: 113.157 ymin: 22.20104 xmax: 113.692 ymax: 22.7726
Geodetic CRS: WGS 84
# A tibble: 1 × 5
adcode name center level geometry
<chr> <chr> <chr> <chr> <POLYGON [°]>
1 442000 中山市 113.382391,22.521113 city ((113.5687 22.41193, 113.5666 22.412…
Simple feature collection with 1 feature and 4 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: 115.9267 ymin: 20.58265 xmax: 116.9338 ymax: 21.12693
Geodetic CRS: WGS 84
# A tibble: 1 × 5
adcode name center level geometry
<chr> <chr> <chr> <chr> <MULTIPOLYGON [°]>
1 442100 东沙群岛 116.887312,20.617512 city (((115.9433 21.09745, 115.95 21.11…
Simple feature collection with 1 feature and 4 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: 108.9287 ymin: 19.17894 xmax: 109.7694 ymax: 19.92575
Geodetic CRS: WGS 84
# A tibble: 1 × 5
adcode name center level geometry
<chr> <chr> <chr> <chr> <MULTIPOLYGON [°]>
1 460400 儋州市 109.576782,19.517486 city (((109.4322 19.91302, 109.4253 19.91…
Simple feature collection with 1 feature and 4 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: 97.8483 ymin: 39.65426 xmax: 98.52018 ymax: 39.99979
Geodetic CRS: WGS 84
# A tibble: 1 × 5
adcode name center level geometry
<chr> <chr> <chr> <chr> <MULTIPOLYGON [°]>
1 620200 嘉峪关市 98.277304,39.786529 city (((97.85974 39.7169, 97.85827 39.71…
Code
# Exclude some problematic files.X =list.files("./GeoMapData_CN/citys", recursive = T, full.names = T)X2=X[-which(X %in%c("./GeoMapData_CN/citys/620200.json","./GeoMapData_CN/citys/460400.json","./GeoMapData_CN/citys/442100.json","./GeoMapData_CN/citys/442000.json","./GeoMapData_CN/citys/441900.json" ))]# Reload the list of files.map_list <-lapply(X = X2,FUN = sf::read_sf)
Code
# Print the number of files.length(map_list)
[1] 329
Code
# Combine all the sf objects into one.province_map <-Reduce("rbind", map_list)
Code
# This code would display the combined map.# library(leaflet)# library(sf)## json_data <- province_map### pal <- colorNumeric(c("red", "green", "blue"), 1:10)## leaflet(json_data) %>%# addTiles() %>%# addPolygons(smoothFactor = 0.3, fillOpacity = 0.1)
13 Displaying All Map Providers
This section shows how to list all available map providers in the leaflet package.
Code
# Display the list of available map providers.providers
---title: "Interactive Maps with Leaflet in R"author: "Tony Duan"execute: warning: false error: falseformat: html: toc: true toc-location: right code-fold: show code-tools: true number-sections: true code-block-bg: true code-block-border-left: "#31BAE9" code-copy: true---This document provides a comprehensive guide to creating interactive maps using the `leaflet` package in R. We will explore various features of `leaflet`, from basic map creation to advanced customizations like adding markers, popups, and choropleth layers. This guide is intended for users who have a basic understanding of R and are interested in data visualization and geospatial analysis.# Getting Started: Loading Libraries and DataFirst, we need to load the necessary R libraries. We'll be using `tidyverse` for data manipulation, `sf` for working with spatial data, `leaflet` for creating the maps, and `geojsonio` for reading GeoJSON files.```{r}# Load the tidyverse package for data manipulation and visualization.library(tidyverse)# Load the sf package for working with simple features, a standardized way to encode spatial vector data.library(sf)# Load the leaflet package for creating interactive maps.library(leaflet)# Load the geojsonio package for reading and writing GeoJSON.library(geojsonio)# Load the leaflet.extras package for additional leaflet features.library(leaflet.extras)```# Displaying a Basic Map with OpenStreetMapHere, we'll create a simple map using the default OpenStreetMap tiles and add a marker for a specific location.```{r}# Create a leaflet map widget.m <-leaflet() %>%# Add the default OpenStreetMap map tiles.addTiles() %>%# Add a marker to the map at the specified longitude and latitude.addMarkers(lng=174.768, lat=-36.852, popup="The birthplace of R")# Display the map.m```# Using Google Maps as a BasemapInstead of the default OpenStreetMap, you can use other tile providers like Google Maps.```{r}leaflet() |># Add Google Maps tiles using the specified URL template.addTiles(urlTemplate ="https://mt1.google.com/vt/lyrs=m&x={x}&y={y}&z={z}") |># Set the initial view of the map with a specific center and zoom level.setView(116.347817690225, 39.997202126977, zoom =16) |># Add a marker to the map.addMarkers(116.347817690225, 39.997202126977)```# Using Third-Party Map ProvidersLeaflet supports a wide variety of third-party map providers. You can find a list of available providers in the `providers` object.```{r}# You can uncomment these lines to try a different map provider.# m <- leaflet() %>% setView(lng = -71.0589, lat = 42.3601, zoom = 10)# m %>% addProviderTiles(providers$Stadia.StamenToner)```# Adding PopupsPopups are small boxes containing arbitrary HTML that point to a specific point on the map.```{r}# Create HTML content for the popup.content <-paste(sep ="<br/>","<b><a href='https://www.samurainoodle.com/'>Samurai Noodle</a></b>","606 5th Ave. S","Seattle, WA 98138")# Create a map and add a popup.leaflet() %>%addTiles() %>%setView(-122.327298, 47.597131,zoom =12) %>%addPopups(-122.327298, 47.597131, content,# You can customize the popup options, for example, to remove the close button.options =popupOptions(closeButton =FALSE) )```# Adding Markers from a Data FrameYou can add multiple markers to a map from a data frame.```{r}# Load the htmltools package for working with HTML.library(htmltools)# Create a data frame with marker information.df <-read.csv(textConnection("Name,Lat,LongSamurai Noodle,47.597131,-122.327298Kukai Ramen,47.6154,-122.327157Tsukushinbo,47.59987,-122.326726"))# Create a map and add markers from the data frame.leaflet(df) %>%addTiles() %>%addMarkers(~Long, ~Lat, popup =~htmlEscape(Name))```# Adding LabelsLabels are similar to popups but are always displayed or displayed on mouseover.```{r}# Load the htmltools package.library(htmltools)# Create a data frame with marker information.df <-read.csv(textConnection("Name,Lat,LongSamurai Noodle,47.597131,-122.327298Kukai Ramen,47.6154,-122.327157Tsukushinbo,47.59987,-122.326726"))# Create a map and add markers with labels.leaflet(df) %>%addTiles() %>%addMarkers(~Long, ~Lat, label =~htmlEscape(Name))```# Creating a World Choropleth MapNow, let's create a choropleth map of the world, where countries are colored based on their per capita GDP.## Loading Geospatial and GDP DataWe'll start by loading the world administrative boundaries from a GeoJSON file and then merge it with per capita GDP data from an Excel file.```{r}# The maptools package is now archived, so we are not using it.# install.packages("https://cran.r-project.org/src/contrib/Archive/maptools/maptools_1.1-8.tar.gz")``````{r}# Read the world administrative boundaries from a GeoJSON file.json_data=read_sf("world-administrative-boundaries.geojson")``````{r}# Convert the sf object to a data frame.map_df <-as.data.frame(json_data)``````{r}# This is an example of how you could create a data frame manually.# name<-c("Ghana", "Grenada", "Guyana", "India", "Jamaica", "Kenya", "United States","Canada")# val<-c(1,2,4,5,5,1000,20000, 100)# per_gdp_usd<-data.frame(name,val)``````{r}# Load the openxlsx and readxl packages for reading Excel files.library(openxlsx)library(readxl)# Read the world GDP data from an Excel file and clean up the country names to match the GeoJSON data.per_gdp_usd=read_excel('world data.xlsx') %>%mutate(name=case_when( name =="United States"~"United States of America", name =="Russia"~"Russian Federation", name =="U.K. of Great Britain and Northern Ireland"~"United Kingdom", name =="South Korea"~"Republic of Korea", name =="Lao People's Democratic Republic"~"Laos",TRUE~ name ))```## Merging and Preparing the DataWe'll merge the geospatial data with the GDP data and convert it back to an `sf` object.```{r}# These lines are for debugging and checking the data.# test=full_join(map_df, per_gdp_usd, by="name")# left =test %>% filter(is.na(iso3)==TRUE)# right=test %>% filter(is.na(per_gdp_total)==TRUE)``````{r}# Merge the map data frame with the GDP data frame by country name.map_df002 <-merge(map_df, per_gdp_usd, by.x ="name", by.y ="name")``````{r}# Get a glimpse of the merged data frame.glimpse(map_df002)``````{r}# Convert the merged data frame back to an sf object.map_sf002 <- sf::st_as_sf(map_df002, sf_column_name ="geometry")```## Creating the Choropleth MapNow we can create the choropleth map.```{r}# Create a color palette for the choropleth map.pal <-colorNumeric("viridis", NULL)# Create the leaflet map.leaflet(map_sf002) %>%addTiles() %>%# Add polygons to the map, representing the countries.addPolygons(smoothFactor =0.3, fillOpacity =0.5,weight =1,# Set the fill color based on the per capita GDP.fillColor =~pal(per_gdp_usd),# Create a popup with information about the country.popup =~paste0("地区:", name, "<br/>","<hr/>","人均gpd:", per_gdp_usd, "(千 美元)", "<br/>" ),# Create a label with more detailed information.label =lapply(paste0("地区:", "<b>", map_sf002$name, "</b>", "<br/>","人均gpd 美元:", round(map_sf002$per_gdp_usd/1000), "K <br/>","总gpd 美元:", round(map_sf002$per_gdp_total/1000000), "M <br/>" ), htmltools::HTML) ) %>%# Add a legend to the map.addLegend(position ="bottomright", title ="人均gpd(美元)",pal = pal, values =~per_gdp_usd, opacity =1.0 )```# China MapsNow we will create several maps of China, including a map of a single city, a choropleth map of all provinces, and a map of a single province with its cities.## China One City Map (Shenzhen)Here, we'll create a map of Shenzhen.```{r}# Read the GeoJSON data for Shenzhen.json_data <- sf::read_sf("./GeoMapData_CN/citys/440300.json")# You can also load the data directly from a URL.# json_data=read_sf("https://geo.datav.aliyun.com/areas_v2/bound/440300_full.json")```Shenzhen City:```{r}# Create a color palette.pal <-colorNumeric("viridis", NULL)# Create the map of Shenzhen.leaflet(json_data) %>%addTiles() %>%addPolygons(smoothFactor =0.3, fillOpacity =0.1)```## All China Each Province GDP MapNext, we'll create a choropleth map of China's provinces, colored by their per capita GDP in 2022.```{r}# Read the GeoJSON data for China's provinces.json_data=read_sf("https://geo.datav.aliyun.com/areas_v2/bound/100000_full.json")```China 2022 Per Capita GDP by Province (USD):```{r}# Load the openxlsx and readxl packages.library(openxlsx)library(readxl)# Read the GDP data for China's provinces.per_gdp_usd=read_excel('china gdp2022.xlsx')``````{r}# Convert the sf object to a data frame.map_df <-as.data.frame(json_data)``````{r}# Merge the map data with the GDP data.map_df002 <-merge(map_df, per_gdp_usd, by.x ="name", by.y ="city")``````{r}# Convert the merged data frame back to an sf object.map_sf002 <- sf::st_as_sf(map_df002, sf_column_name ="geometry")``````{r}# Create a color palette.pal <-colorNumeric("viridis", NULL)# Create the choropleth map of China's provinces.leaflet(map_sf002) %>%addTiles() %>%addPolygons(smoothFactor =0.3, fillOpacity =0.5,weight =1,fillColor =~pal(per_gpd_usd),popup =~paste0("地区:", name, "<br/>","<hr/>","人均gpd:", per_gpd_usd, "(美万)", "<br/>" ),label =lapply(paste0("地区:", "<b>", map_sf002$name, "</b>", "<br/>","人均gpd 美元:", map_sf002$per_gpd_usd, "<br/>","人均gpd 人民币:", map_sf002$per_gpd_rmb, "<br/>","人口:", round(map_sf002$total_gpd_rmb/map_sf002$per_gpd_rmb), "<br/>" ), htmltools::HTML) ) %>%addLegend(position ="bottomright", title ="人均gpd(美元)",pal = pal, values =~per_gpd_usd, opacity =1.0 )```GDP data source: National Bureau of Statistics of China## China One Province Map with Each City's GDP (Guangdong)Here, we'll create a choropleth map of Guangdong province, with each city colored by its per capita GDP in 2021.```{r}# Read the GeoJSON data for Guangdong province.json_data <- sf::read_sf("./GeoMapData_CN/province/440000.json")```Guangdong 2021 Per Capita GDP by City (USD):```{r}# Load the openxlsx and readxl packages.library(openxlsx)library(readxl)# Read the GDP data for Guangdong's cities.per_gdp_usd=read_excel('guangdong city gdp2021.xlsx')``````{r}# Convert the sf object to a data frame.map_df <-as.data.frame(json_data)``````{r}# Merge the map data with the GDP data.map_df002 <-merge(map_df, per_gdp_usd, by.x ="name", by.y ="city")``````{r}# Convert the merged data frame back to an sf object.map_sf002 <- sf::st_as_sf(map_df002, sf_column_name ="geometry")```Data source: Guangdong Statistical Yearbook 2022```{r}# Create a color palette.pal <-colorNumeric("viridis", NULL)# Create the choropleth map of Guangdong province.leaflet(map_sf002) %>%addTiles() %>%addPolygons(smoothFactor =0.3, fillOpacity =0.5,weight =1,fillColor =~pal(per_gpd_usd),popup =~paste0("城市:", name, "<br/>","<hr/>","人均gpd:", per_gpd_usd, "(美万)", "<br/>" ),label =lapply(paste0("城市:", "<b>", map_sf002$name, "</b>", "<br/>","人均gpd 美元:", map_sf002$per_gpd_usd, "<br/>","人均gpd 人民币:", map_sf002$per_gpd_rmb, "<br/>","人口:", round(map_sf002$total_gpd_rmb*10000000/map_sf002$per_gpd_rmb), "<br/>" ), htmltools::HTML) ) %>%addLegend(position ="bottomright", title ="人均gpd(美元)",pal = pal, values =~per_gpd_usd, opacity =1.0 )```https://zh.wikipedia.org/wiki/%E5%B9%BF%E4%B8%9C%E5%90%84%E5%9C%B0%E7%BA%A7%E5%B8%82%E5%9C%B0%E5%8C%BA%E7%94%9F%E4%BA%A7%E6%80%BB%E5%80%BC%E5%88%97%E8%A1%A8# China Province MapThis section shows how to create a simple map of China's provinces and add markers for the provincial capitals.```{r}# Load the leaflet and sf packages.library(leaflet)library(sf)# Read the GeoJSON data for China's provinces.json_data <- sf::read_sf("./GeoMapData_CN/china.json")# You can also load the data from a URL.# json_data=read_sf("https://geo.datav.aliyun.com/areas_v2/bound/100000_full.json")# Create a color palette.pal <-colorNumeric("viridis", NULL)# Create the map of China's provinces.m=leaflet(json_data) %>%addTiles() %>%addPolygons(smoothFactor =0.3, fillOpacity =0.1)# Display the map.m```## Add Provincial CapitalsNow, let's add the provincial capitals to the map.```{r}# Read the GeoJSON data for China's provinces.China=read_sf("https://geo.datav.aliyun.com/areas_v2/bound/100000_full.json")``````{r}# Extract the coordinates of the provincial capitals.China002=China %>%as_data_frame() %>%mutate(center2=as.character(center) %>%str_replace('c','_')%>%str_replace('[(]','') %>%str_replace('[)]','') )``````{r}# Separate the coordinates into x and y columns.China003=China002%>%separate(center2, c("x", "y"), ", ")``````{r}# Add the provincial capitals to the map.China_point = China003 %>%slice(-35)m %>%addCircles(data = China_point,lng =~as.numeric(x), lat =~as.numeric(y),color ="red",weight =10,fillOpacity =2)```# China Province and City MapThis section demonstrates how to load and combine GeoJSON files for all provinces and their cities.```{r}# Get a list of all province GeoJSON files.map_list <-lapply(X =list.files("./GeoMapData_CN/province", recursive = T, full.names = T),FUN = sf::read_sf)# Print the number of files.length(map_list)``````{r}# Check for any files that don't have 10 columns.for (i inc(1:length(map_list))){#print(i)#print(dim(map_list[[i]]))#print(ncol(map_list[[i]]))if(ncol(map_list[[i]])!=10){print(map_list[[i]])} }``````{r}# Exclude some problematic files.X =list.files("./GeoMapData_CN/province", recursive = T, full.names = T)X2=X[-which(X %in%c("./GeoMapData_CN/province/710000.json" ))]# Reload the list of files.map_list <-lapply(X = X2,FUN = sf::read_sf)``````{r}# Print the number of files.length(map_list)``````{r}# Combine all the sf objects into one.province_map <-Reduce("rbind", map_list)``````{r}# This code would display the combined map.# library(leaflet)# library(sf)## json_data <- province_map### pal <- colorNumeric(c("red", "green", "blue"), 1:10)## leaflet(json_data) %>%# addTiles() %>%# addPolygons(smoothFactor = 0.3, fillOpacity = 0.1)```# China City and District MapThis section is similar to the previous one, but it loads GeoJSON files for cities and their districts.```{r}# Get a list of all city GeoJSON files.map_list <-lapply(X =list.files("./GeoMapData_CN/citys", recursive = T, full.names = T),FUN = sf::read_sf)# Print the number of files.length(map_list)``````{r}# Check for any files that don't have 10 columns.for (i inc(1:length(map_list))){#print(i)#print(dim(map_list[[i]]))#print(ncol(map_list[[i]]))if(ncol(map_list[[i]])!=10){print(map_list[[i]])} }``````{r}# Exclude some problematic files.X =list.files("./GeoMapData_CN/citys", recursive = T, full.names = T)X2=X[-which(X %in%c("./GeoMapData_CN/citys/620200.json","./GeoMapData_CN/citys/460400.json","./GeoMapData_CN/citys/442100.json","./GeoMapData_CN/citys/442000.json","./GeoMapData_CN/citys/441900.json" ))]# Reload the list of files.map_list <-lapply(X = X2,FUN = sf::read_sf)``````{r}# Print the number of files.length(map_list)``````{r}# Combine all the sf objects into one.province_map <-Reduce("rbind", map_list)``````{r}# This code would display the combined map.# library(leaflet)# library(sf)## json_data <- province_map### pal <- colorNumeric(c("red", "green", "blue"), 1:10)## leaflet(json_data) %>%# addTiles() %>%# addPolygons(smoothFactor = 0.3, fillOpacity = 0.1)```# Displaying All Map ProvidersThis section shows how to list all available map providers in the `leaflet` package.```{r, attr.output='.details summary="providers"'}# Display the list of available map providers.providers```# Session InformationThis section provides information about the current R session, including the versions of the loaded packages.```{r, attr.output='.details summary="sessionInfo()"'}# Display the session information.sessionInfo()```# ResourcesHere are some useful resources for learning more about `leaflet` and working with geospatial data in R.https://rstudio.github.io/leaflet/https://github.com/Lchiffon/leafletCNhttps://github.com/longwosion/geojson-map-chinahttps://xiangyun.rbind.io/2022/02/draw-china-maps/https://datav.aliyun.com/portal/school/atlas/area_selector